package com.bxs.demo;

import org.pcap4j.core.*;
import org.pcap4j.packet.IpV4Packet;
import org.pcap4j.packet.Packet;
import org.pcap4j.util.NifSelector;

import java.io.EOFException;
import java.io.IOException;
import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeoutException;

public class Loop {

    private static final String COUNT_KEY = Loop.class.getName() + ".count";
    private static final int COUNT = Integer.getInteger(COUNT_KEY, 5);
    private static final String READ_TIMEOUT_KEY = Loop.class.getName() + ".readTimeout";
    private static final int READ_TIMEOUT = Integer.getInteger(READ_TIMEOUT_KEY, 10); // [ms]
    private static final String SNAPLEN_KEY = Loop.class.getName() + ".snaplen";
    private static final int SNAPLEN = Integer.getInteger(SNAPLEN_KEY, 65536); // [bytes]

    private Loop() {}

    public static void main(String[] args) throws PcapNativeException, NotOpenException {
//        String filter = “ip and tcp and (dst host 127.0.0.1 and dst port 80)”; // 设置过滤的字符串

        // 设置要抓包的网卡
        PcapNetworkInterface nif = null;
//        try {
//            nif = new NifSelector().selectNetworkInterface(); // 这个方法提供用户输入网卡的序号
//        } catch (IOException e) {
//            e.printStackTrace();
//            return;
//        }
        try {
            nif = Pcaps.getDevByAddress(InetAddress.getLocalHost());
        } catch (UnknownHostException e) {
            e.printStackTrace();
            return;
        }
        if (nif == null) {
            return;
        }

        // 实例化一个捕获报文的对象，设置抓包参数：长度，混杂模式，超时时间等
        final PcapHandle handle = nif.openLive(SNAPLEN, PcapNetworkInterface.PromiscuousMode.PROMISCUOUS, 10);

        // 设置过滤器
//        if (filter.length() != 0) {
//            handle.setFilter(filter, BpfCompileMode.OPTIMIZE);
//        }

        // 观察者模式，抓到报文回调gotPacket方法处理报文内容
//        PacketListener listener =
//                new
//            PacketListener() {
//                    @Override
//                    public void gotPacket(Packet packet) {
//                        // 抓到报文走这里...
//                        System.out.println(handle.getTimestampPrecision());
//                        System.out.println(packet);
//                    }
//                };

        PacketListener listener = new PacketListener() {
            @Override
            public void gotPacket(PcapPacket packet) {
                IpV4Packet ipV4Packet = packet.get(IpV4Packet.class);
                System.out.println(ipV4Packet);
            }
        };

        // 直接使用loop无限循环处理包
        try {
            ExecutorService executorService = Executors.newFixedThreadPool(5);
            handle.loop(100, listener, executorService); // COUNT设置为抓包个数，当为-1时无限抓包
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        handle.close();
    }
}

